package elastic.onestep.mongo;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.WriteConcern;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable;
import elastic.onestep.config.MongoConfig;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

public class Mongodb {
    private static Logger logger = LoggerFactory.getLogger(Mongodb.class);
    private static Mongodb ourInstance = new Mongodb();
    private static MongoClient mongoClient;
    private String defaultDbName = "test";

    public static Mongodb getInstance() {
        return ourInstance;
    }

    private Mongodb() {
        run();
    }

    /**
     * 使用单例模式初始化mongo客户端
     */
    private void run() {
        mongoClient = new MongoClient(MongoConfig.getADDRESS(), MongoConfig.getPORT());
        MongoClientOptions.Builder options = new MongoClientOptions.Builder();
        options.cursorFinalizerEnabled(true);
        //连接池300个连接限制
        options.connectionsPerHost(300);
        //超时时间
        options.connectTimeout(30000);
        options.maxWaitTime(5000);
        //socket超时时间，无限制
        options.socketTimeout(0);
        //线程队列数
        options.threadsAllowedToBlockForConnectionMultiplier(5000);
        options.writeConcern(WriteConcern.ACKNOWLEDGED);
        options.build();
    }

    /**
     * 得到数据库，不存在存入数据时自动创建
     */
    protected MongoDatabase getDB(String daName) {
        if (daName != null || daName != "") {
            MongoDatabase mongoDatabase = mongoClient.getDatabase(daName);
            return mongoDatabase;
        } else {
            System.out.println("dbName is null");
            System.exit(0);
            return null;
        }
    }


    /**
     * 得到某个集合的所有文档
     */
    protected MongoCollection<Document> getColl(String dbName, String collName) {
        if (dbName == null || dbName == "") {
            System.out.println("dbName is null");
            System.exit(0);
            return null;
        }
        if (collName == null || collName == "") {
            System.out.println("collName is null");
            System.exit(0);
            return null;
        }
        MongoCollection<Document> collection = getDB(dbName).getCollection(collName);
        return collection;
    }

    /**
     * 得到默认的集合名字
     */
    protected MongoCollection<Document> getColl(String collName) {
        return this.getColl(defaultDbName, collName);
    }

    /**
     * 得到目前mongo服务下所有数据库的名字
     */
    public List<String> getAllDataBases() {
        return StreamSupport.stream(mongoClient.listDatabaseNames().spliterator(), true).collect(Collectors.toList());
    }

    /**
     * 关闭Mongodb
     */

    public void close() {
        if (mongoClient != null) {
            mongoClient.close();
            System.out.println("Client has'n closed");
        }
    }

    /**
     * 删除一个数据库
     */
    public void dropDB(String name) {
        getDB(name).drop();
        System.out.println("DataBase--" + name + " has'n dropped");
    }

    /**
     * 获取所有collection对象
     */
    public List<String> getAllColletions(String dbName) {
        MongoIterable<String> colls = getDB(dbName).listCollectionNames();
        return StreamSupport.stream(colls.spliterator(), true).collect(Collectors.toList());
    }

    public void insertTest(MongoCollection<Document> mdbColl) {
        try {
            InputStream is = new FileInputStream("/Users/unclewang/Idea_Projects/unclewang/src/main/resources/json/evidence.json");
            //InputStream is = new FileInputStream("/Users/unclewang/Downloads/training.json");
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String line;
            List<Document> batch = new ArrayList<>();
            int num = 0;
            while ((line = br.readLine()) != null) {
                num++;
                Document document = Document.parse(line);
                batch.add(document);
                if (batch.size() == 500) {
                    mdbColl.insertMany(batch);
                    logger.info("已插入" + num);
                    batch.clear();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Mongodb mdb = Mongodb.getInstance();
        //mdb.dropDB("baiduQA");
        MongoCollection<Document> mdbColl = mdb.getColl("baiduQA", "evidence");
        mdb.insertTest(mdbColl);
//        mdbColl.find().forEach((Block<? super Document>) document -> {
//            System.out.println(document.toJson());
//        });

//        mdb.getAllDataBases().stream().forEach(System.out::println);
//        mdb.getAllColletions("admin").stream().forEach(System.out::println);

    }

}
